package com.ideaplugin.datamanager.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import com.google.common.collect.Lists;
import com.ideaplugin.datamanager.entity.TableAuth;
import com.ideaplugin.datamanager.entity.TableColumn;
import com.ideaplugin.datamanager.entity.TableColumnAuth;
import com.ideaplugin.datamanager.entity.table.TableAuthTableDef;
import com.ideaplugin.datamanager.entity.table.TableColumnAuthTableDef;
import com.ideaplugin.datamanager.entity.table.TableColumnTableDef;
import com.ideaplugin.datamanager.manager.TableAuthManager;
import com.ideaplugin.datamanager.manager.TableColumnAuthManager;
import com.ideaplugin.datamanager.manager.TableColumnManager;
import com.ideaplugin.datamanager.model.common.CommonResultCode;
import com.ideaplugin.datamanager.model.common.DwhException;
import com.ideaplugin.datamanager.model.request.RoleColumnParam;
import com.ideaplugin.datamanager.model.request.TableColumnParam;
import com.ideaplugin.datamanager.model.request.TableColumnSortParam;
import com.ideaplugin.datamanager.model.response.TableColumnVo;
import com.ideaplugin.datamanager.service.TableColumnService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TableColumnServiceImpl implements TableColumnService {

    @Resource
    private TableColumnManager tableColumnManager;
    @Resource
    private TableColumnAuthManager tableColumnAuthManager;
    @Resource
    private TableAuthManager tableAuthManager;

    /**
     * 查询统维度、
     */
    @Override
    public List<TableColumnVo> list(Long tableInfoId) {
        final List<TableColumn> list = tableColumnManager.queryChain()
                .from(TableColumn.class)
                .orderBy(TableColumnTableDef.TABLE_COLUMN.ORDER_NO, true)
                .where(TableColumnTableDef.TABLE_COLUMN.TABLE_INFO_ID.eq(tableInfoId))
                .list();
        final List<TableColumnVo> tableColumns = list.stream().map(col -> {
            TableColumnVo vo = new TableColumnVo();
            BeanUtils.copyProperties(col, vo);
            if (StringUtils.isNotBlank(col.getDefaultValue())) {
                vo.setDefaultValue(JSON.parse(col.getDefaultValue()));
            }
            return vo;
        }).collect(Collectors.toList());
        return tableColumns;
    }

    /**
     * 增加或修改维度
     *
     * @param param StatisticalDataCodeParam
     */
    @Override
    public Boolean saveOrUpdate(TableColumnParam param) {
        TableColumn tableColumn = BeanUtil.copyProperties(param, TableColumn.class);
        if (Objects.nonNull(param.getDefaultValue())) {
            tableColumn.setDefaultValue(JSON.toJSONString(param.getDefaultValue()));
        }
        //add
        if (Objects.isNull(param.getId())) {
            final Integer orderNo = param.getOrderNo() + 1;
            tableColumnManager.updateChain().from(TableColumn.class)
                    .where(TableColumnTableDef.TABLE_COLUMN.TABLE_INFO_ID.eq(tableColumn.getTableInfoId()))
                    .where(TableColumnTableDef.TABLE_COLUMN.ORDER_NO.ge(orderNo))
                    .set(TableColumnTableDef.TABLE_COLUMN.ORDER_NO, TableColumnTableDef.TABLE_COLUMN.ORDER_NO.add(1))
                    .update();
            tableColumn.setOrderNo(orderNo);
        }
        return tableColumnManager.saveOrUpdate(tableColumn);
    }

    /**
     * 删除相关权限
     *
     * @param tableInfoId
     * @param columnCode
     */
    private void removeColumnAuth(Long tableInfoId, String columnCode) {

        final List<TableColumnAuth> columnAuths = tableColumnAuthManager.queryChain()
                .from(TableColumnAuth.class)
                .where(TableColumnAuthTableDef.TABLE_COLUMN_AUTH.TABLE_INFO_ID.eq(tableInfoId))
                .where(TableColumnAuthTableDef.TABLE_COLUMN_AUTH.COLUMN_CODE.eq(columnCode))
                .list();
        if (CollUtil.isEmpty(columnAuths)) {
            return;
        }
        tableColumnAuthManager.removeByIds(columnAuths.stream().map(TableColumnAuth::getId).collect(Collectors.toList()));
        final Set<Long> userIds = columnAuths.stream().map(TableColumnAuth::getRoleId).collect(Collectors.toSet());
        final List<TableAuth> userTableAuth = tableAuthManager.queryChain()
                .from(TableAuth.class)
                .where(TableAuthTableDef.TABLE_AUTH.TABLE_INFO_ID.eq(tableInfoId))
                .where(TableAuthTableDef.TABLE_AUTH.ROLE_ID.in(userIds))
                .list();

        if (CollUtil.isEmpty(userTableAuth)) {
            return;
        }
        userTableAuth.forEach(tableAuth -> {
            if (Objects.nonNull(tableAuth.getAuthColumnCount()) && tableAuth.getAuthColumnCount() > 0) {
                tableAuth.setAuthColumnCount(tableAuth.getAuthColumnCount() - 1);
                tableAuthManager.updateById(tableAuth);
            }
        });

    }

    /**
     * 删除维度
     */
    @Override
    public Boolean delete(Long id) {
        TableColumn tableColumn = tableColumnManager.getById(id);
        this.removeColumnAuth(tableColumn.getTableInfoId(), tableColumn.getColumnCode());
        return tableColumnManager.removeById(id);
    }


    @Override
    public List<String> listRoleColumnCode(RoleColumnParam roleColumnParam) {
        boolean exists = tableAuthManager.queryChain()
                .from(TableAuth.class)
                .where(TableAuthTableDef.TABLE_AUTH.TABLE_INFO_ID.eq(roleColumnParam.getTableInfoId()))
                .where(TableAuthTableDef.TABLE_AUTH.ROLE_ID.eq(roleColumnParam.getRoleId()))
                .exists();
        if (!exists) {
            return Lists.newArrayList();
        }
        TableColumnAuth column = tableColumnAuthManager.queryChain()
                .from(TableColumnAuth.class)
                .where(TableColumnAuthTableDef.TABLE_COLUMN_AUTH.TABLE_INFO_ID.eq(roleColumnParam.getTableInfoId()))
                .where(TableColumnAuthTableDef.TABLE_COLUMN_AUTH.ROLE_ID.eq(roleColumnParam.getRoleId()))
                .one();
        if (Objects.isNull(column)) {
            return Lists.newArrayList();
        }
        return JSON.parseArray(column.getColumnCode(), String.class);
    }

    @Override
    public Boolean sortTableColumn(TableColumnSortParam param) {
        TableColumn tableColumn = tableColumnManager.getById(param.getId());
        if (Objects.isNull(tableColumn)) {
            throw new DwhException(CommonResultCode.EXCEPTION.code, "数据不存在");
        }
        final Integer orderNo = param.getOrderNo();
        tableColumnManager.updateChain()
                .from(TableColumn.class)
                .where(TableColumnTableDef.TABLE_COLUMN.TABLE_INFO_ID.eq(tableColumn.getTableInfoId()))
                .where(TableColumnTableDef.TABLE_COLUMN.ORDER_NO.ge(orderNo))
                .set(TableColumnTableDef.TABLE_COLUMN.ORDER_NO, TableColumnTableDef.TABLE_COLUMN.ORDER_NO.add(1))
                .update();
        tableColumn.setOrderNo(orderNo);
        return tableColumnManager.updateById(tableColumn);
    }

    public static void main(String[] args) {
        String str = null;
        System.out.println(JSON.toJSONString(str, JSONWriter.Feature.NullAsDefaultValue));

        System.out.println(JSON.parse(JSON.toJSONString(str)));

    }
}
